package com.demo;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;

import javax.swing.SwingUtilities;
import javax.swing.tree.DefaultMutableTreeNode;

import com.demo.data.Configuration;
import com.demo.data.FileNode;
import com.demo.ui.InitView;
import com.demo.ui.MainView;
import com.demo.ui.TreeView;
import com.demo.utils.ConfigReader;
import com.demo.utils.Logger;

public class Main {

	public static void main(String[] args) {
		Logger.d("app start");
		initConfig();

		if (Configuration.getInstance().getWorkspace() == null
				|| Configuration.getInstance().getWorkspace().isEmpty()) {
			final InitView initView = InitView.newInstance("D:\\");
			initView.getDoneButton().addActionListener(new ActionListener() {

				@Override
				public void actionPerformed(ActionEvent e) {
					if (initView.getPath().isEmpty()) {
						return;
					}
					File file = new File(initView.getPath());
					if (!file.exists()) {
						file.mkdirs();
					}
					Configuration.getInstance().setWorkspace(initView.getPath());
					saveConfig();
					initView.close();
					start();
				}
			});
		} else {
			start();
		}
	}

	private static void start() {
		SwingUtilities.invokeLater(new Runnable() {

			@Override
			public void run() {
				FileNode root = new FileNode();
				root.setName(Configuration.getInstance().getWorkspace());
				root.setFile(new File(Configuration.getInstance().getWorkspace()));
				root.setDummyRoot(true);
				final MainView mainView = MainView.newInstance(root);
				mainView.addWindowListener(new WindowAdapter() {
					@Override
					public void windowClosing(WindowEvent e) {
						saveConfig();
					}
				});
				mainView.setNewFileClickListener(new MainView.OnMenuItemClickListener() {

					@Override
					public void onClick(Object object) {
						FileNode node = (FileNode) object;
						File file = node.getFile();
						if (file.exists()) {
							return;
						}
						try {
							file.createNewFile();
						} catch (IOException e) {
							e.printStackTrace();
						}
						if (!node.isOpen()) {
							node.setOpen(true);
							mainView.addTab(node);
							mainView.getContentArea().setText(openFile(node));
						}
					}
				});
				mainView.setNewProjectClickListener(new MainView.OnMenuItemClickListener() {

					@Override
					public void onClick(Object object) {
						FileNode node = (FileNode) object;
						File file = node.getFile();
						if (file.exists()) {
							return;
						}
						file.mkdir();
					}
					
				});
				mainView.setSaveClickListener(new MainView.OnMenuItemClickListener() {

					@Override
					public void onClick(Object object) {
						FileNode node = (FileNode) object;
						String content = mainView.getContentText();
						saveFile(node, content);
					}
				});
				final TreeView treeView = mainView.getExplorerTree();
				treeView.setOnTreeClickListener(new TreeView.SimpleTreeClickListener() {

					@Override
					public void onDoubleClick(MouseEvent e) {
						DefaultMutableTreeNode node = ((DefaultMutableTreeNode) treeView.getTree().getSelectionPath()
								.getLastPathComponent());
						FileNode fileNode = (FileNode) node.getUserObject();
						mainView.setFilePath(fileNode.getFile().getAbsolutePath());
						if (!fileNode.getFile().isDirectory()) {
							if (!fileNode.isOpen()) {
								fileNode.setOpen(true);
								mainView.addTab(fileNode);
								mainView.getContentArea().setText(openFile(fileNode));
							}
						}
					}
				});
				treeView.setOnTreeNodeLister(new TreeView.SimpleTreeNodeListener() {

					@Override
					public void onRename(FileNode node) {

					}

					@Override
					public void onNewFile(FileNode node) {
						File file = node.getFile();
						if (file.exists()) {
							return;
						}
						try {
							file.createNewFile();
						} catch (IOException e) {
							e.printStackTrace();
						}
					}

					@Override
					public void onNewDir(FileNode node) {
						File file = node.getFile();
						if (file.exists()) {
							return;
						}
						file.mkdir();
					}

					@Override
					public void onDelete(FileNode node) {
						File file = node.getFile();
						file.delete();
					}
				});
			}
		});
	}

	private static String openFile(FileNode node) {
		try {
			FileInputStream in = new FileInputStream(node.getFile());
			BufferedReader reader = new BufferedReader(new InputStreamReader(in));
			String line;
			StringBuilder sb = new StringBuilder();
			while ((line = reader.readLine()) != null) {
				sb.append(line);
				sb.append("\r\n");
			}
			reader.close();
			in.close();
			return sb.toString();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return "";
	}

	private static void saveFile(FileNode node, String content) {
		try {
			FileWriter writer = new FileWriter(node.getFile());
			writer.write(content);
			writer.flush();
			writer.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private static void initConfig() {
		HashMap<String, String> map = ConfigReader.getConfig();
		Configuration config = Configuration.getInstance();
		config.setWorkspace(map.get("workspace"), "");
		config.setProjectName(map.get("project"), "");
		config.setSourcePath(map.get("sourcepath"), "");
		config.setClassesPath(map.get("classpath"), "");
		config.setLibraryPath(map.get("library"), "");
		config.setOutputPath(map.get("output"), "");
		config.setPackageName(map.get("package"), "");
		config.setMainClass(map.get("main"), "");
		Logger.d("initConfig" + Configuration.getInstance().toString());
	}

	private static void saveConfig() {
		Logger.d("saveConfig:" + Configuration.getInstance().toString());
		HashMap<String, String> map = new HashMap<>();
		map.put("workspace", Configuration.getInstance().getWorkspace());
		map.put("project", Configuration.getInstance().getProjectName());
		map.put("sourcepath", Configuration.getInstance().getSourcePath());
		map.put("classpath", Configuration.getInstance().getClassesPath());
		map.put("library", Configuration.getInstance().getLibraryPath());
		map.put("output", Configuration.getInstance().getOutputPath());
		map.put("package", Configuration.getInstance().getPackageName());
		map.put("main", Configuration.getInstance().getMainClass());
		ConfigReader.saveConfig(map);
	}

}
